package com.pshcp.doctor.tool;

import com.external.ws.hisTreatment.dto.TreatmentCanBookDTO;
import com.external.ws.hisTreatment.dto.TreatmentReserveExecuteDTO;
import com.framework.base.BaseDTO;
import com.framework.base.ResultBuilder;
import com.framework.exception.BizException;
import com.framework.thread.ReqComTool;
import com.framework.tool.CommonTool;
import com.framework.util.SystemUtil;
import com.pshcp.common.enums.CommonStatusEnum;
import com.pshcp.doctor.ao.patientreserve.ConfirmTreatmentReserveOperateAO;
import com.pshcp.doctor.ao.patientreserve.SaveTreatmentReserveAO;
import com.pshcp.doctor.ao.patientreserve.TreatmentCanBookAO;
import com.pshcp.doctor.ao.patientreserve.TreatmentReservePageAO;
import com.pshcp.doctor.vo.patientreserve.PatientReserveOperateRecordVO;
import com.pshcp.doctor.vo.patientreserve.PatientReserveRecordVO;
import com.pshcp.domain.dto.PatientReserveRecordDTO;
import com.pshcp.domain.model.Doctor;
import com.pshcp.domain.model.Patient;
import com.pshcp.domain.model.PatientReserveCode;
import com.pshcp.domain.model.PatientReserveOperateRecord;
import com.pshcp.domain.model.PatientReserveRecord;
import com.pshcp.service.DoctorService;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @Description: TODO
 * @Author: xiaoche
 * @Date: 2022/11/21 19:36
 */
public class PatientReserveTool {

    public static void checkGetTreatmentBookTimeList(TreatmentCanBookAO treatmentCanBookAO) throws BizException {
        CommonTool.checkObj(treatmentCanBookAO.getHosDistId(), "10190001");
        CommonTool.checkObj(treatmentCanBookAO.getHosDistId(), "10190004");
        CommonTool.checkString(treatmentCanBookAO.getTreatmentDate(), "10190002");
        CommonTool.checkString(treatmentCanBookAO.getTreatmentLocationNo(), "10190003");
    }

    public static TreatmentCanBookDTO buildTreatmentCanBookDTO(TreatmentCanBookAO treatmentCanBookAO, String itemCode) {
        TreatmentCanBookDTO treatmentCanBookDTO = new TreatmentCanBookDTO();
        treatmentCanBookDTO.setHosDistId(treatmentCanBookAO.getHosDistId());
        treatmentCanBookDTO.setTreatmentDate(treatmentCanBookAO.getTreatmentDate());
        treatmentCanBookDTO.setTreatmentLocationNo(treatmentCanBookAO.getTreatmentLocationNo());
        treatmentCanBookDTO.setItemCode(itemCode);
        return treatmentCanBookDTO;
    }

    /**
     * 审核类型
     * 0：无须审核
     * 1：患者提申请->医生确认
     * 2：医生提申请->患者确认->医生再确认
     * 3：医生提申请->通知患者
     * 4：医生提申请->科秘确认->患者确认
     */
    public static Integer buildApprovalType(Integer type) {
        //0入院，1手术，2激光治疗，3瘢痕治疗，4皮肤治疗，5口腔，6门诊拆线换药，7住院注水，8住院拆线换药，9急诊拆线换药
        if (type == 0 || type == 5 || type == 7 || type == 8 || type == 9) {
            return 0;
        }
        if (type == 1) {
            return 2;
        }
        if (type == 2 || type == 3 || type == 4) {
            return 1;
        }
        if (type == 6) {
            return 3;
        }
        return null;
    }

    public static PatientReserveRecord buildSaveTreatmentReserve(Doctor doctor, Patient patient, PatientReserveCode patientReserveCode, SaveTreatmentReserveAO saveTreatmentReserveAO) {
        PatientReserveRecord patientReserveRecord = new PatientReserveRecord();
        patientReserveRecord.setId(SystemUtil.getId());
        patientReserveRecord.setStatus(CommonStatusEnum.INIT.getCode());
        patientReserveRecord.setCreatedTime(new Date());
        patientReserveRecord.setHandleType(saveTreatmentReserveAO.getHandleType());
        /**
         * 类型 0入院，1手术，2激光治疗，3瘢痕治疗，4皮肤治疗，5口腔，6门诊拆线换药，7住院注水，8住院拆线换药，9急诊拆线换药
         */
        patientReserveRecord.setType(saveTreatmentReserveAO.getType());
        patientReserveRecord.setApprovalType(4);
        patientReserveRecord.setApprovalStatus(0);
        patientReserveRecord.setBizStatus(0);
        patientReserveRecord.setAccessDocId(doctor.getHisDoctorId());
        patientReserveRecord.setDoctorId(doctor.getId());
        patientReserveRecord.setDoctorName(doctor.getName());
        patientReserveRecord.setAccessPatId(patient.getHisPatientId());

        patientReserveRecord.setPatientUserId(patient.getPatientUserId());
        patientReserveRecord.setPatientId(patient.getId());
        patientReserveRecord.setPatName(patient.getName());
        patientReserveRecord.setPatCardType(patient.getPatientCardType());
        patientReserveRecord.setPatCardNo(patient.getPatientCardNo());
        patientReserveRecord.setHosDistId(saveTreatmentReserveAO.getHosDistId());

        patientReserveRecord.setAccessDeptId(saveTreatmentReserveAO.getAccessDeptId());
        patientReserveRecord.setDeptId(saveTreatmentReserveAO.getDeptId());
        patientReserveRecord.setDeptName(saveTreatmentReserveAO.getDeptName());

        patientReserveRecord.setTreatmentDate(saveTreatmentReserveAO.getTreatmentDate());
        patientReserveRecord.setStartTime(saveTreatmentReserveAO.getStartTime());
        patientReserveRecord.setEndTime(saveTreatmentReserveAO.getEndTime());
        patientReserveRecord.setTreatmentLocationCode(saveTreatmentReserveAO.getTreatmentLocationCode());
        patientReserveRecord.setTreatmentLocation(saveTreatmentReserveAO.getTreatmentLocation());
        patientReserveRecord.setWard(saveTreatmentReserveAO.getWard());
        patientReserveRecord.setItemCode(patientReserveCode.getItemCode());
        patientReserveRecord.setTreatmentItem(patientReserveCode.getItemName());
        patientReserveRecord.setItemSubItem(null);
        patientReserveRecord.setPrecautions(saveTreatmentReserveAO.getPrecautions());

        patientReserveRecord.setAccessReserveStatus(0);
        patientReserveRecord.setAccessReserveNo(null);
        // 手术预约诊断信息
        patientReserveRecord.setDiagnose(saveTreatmentReserveAO.getDiagnose());
        patientReserveRecord.setDiagnoseName(saveTreatmentReserveAO.getDiagnoseName());
        // 手术名称
        patientReserveRecord.setOperationName(saveTreatmentReserveAO.getOperationName());
        patientReserveRecord.setOperationNameCode(saveTreatmentReserveAO.getOperationNameCode());
        return patientReserveRecord;
    }

    public static List<PatientReserveOperateRecord> buildPatientReserveOperateRecordList(PatientReserveRecord patientReserveRecord) {
        if (patientReserveRecord.getApprovalType() == 0) {
            return Collections.emptyList();
        }
        List<PatientReserveOperateRecord> list = new ArrayList<>();
        if (patientReserveRecord.getApprovalType() == 1) {
            list.add(buildPatientReserveOperateRecord(patientReserveRecord, 0, 1, 2, 1, patientReserveRecord.getPatientId(), 1));
            list.add(buildPatientReserveOperateRecord(patientReserveRecord, 1, 2, 2, 0, patientReserveRecord.getDoctorId(), 0));
            return list;
        }
        if (patientReserveRecord.getApprovalType() == 2) {
            list.add(buildPatientReserveOperateRecord(patientReserveRecord, 0, 1, 3, 0, patientReserveRecord.getDoctorId(), 1));
            list.add(buildPatientReserveOperateRecord(patientReserveRecord, 1, 2, 3, 1, patientReserveRecord.getPatientId(), 0));
            list.add(buildPatientReserveOperateRecord(patientReserveRecord, 1, 3, 3, 0, patientReserveRecord.getDoctorId(), 0));
            return list;
        }
        if (patientReserveRecord.getApprovalType() == 3) {
            list.add(buildPatientReserveOperateRecord(patientReserveRecord, 0, 1, 2, 0, patientReserveRecord.getDoctorId(), 1));
            list.add(buildPatientReserveOperateRecord(patientReserveRecord, 2, 2, 2, 1, patientReserveRecord.getPatientId(), 1));
            return list;
        }
        if (patientReserveRecord.getApprovalType() == 4) {
            list.add(buildPatientReserveOperateRecord(patientReserveRecord, 0, 1, 3, 0, patientReserveRecord.getDoctorId(), 1));
            list.add(buildPatientReserveOperateRecord(patientReserveRecord, 1, 2, 3, 2, null, 0));
            list.add(buildPatientReserveOperateRecord(patientReserveRecord, 1, 3, 3, 1, patientReserveRecord.getPatientId(), 0));
            return list;
        }
        return Collections.emptyList();
    }

    private static PatientReserveOperateRecord buildPatientReserveOperateRecord(PatientReserveRecord patientReserveRecord, Integer type, Integer currentProcedure, Integer totalProcedure, Integer userType, Long userId, Integer bizStatus) {
        PatientReserveOperateRecord patientReserveOperateRecord = new PatientReserveOperateRecord();
        patientReserveOperateRecord.setId(SystemUtil.getId());
        patientReserveOperateRecord.setStatus(CommonStatusEnum.INIT.getCode());
        patientReserveOperateRecord.setCreatedTime(new Date());
        patientReserveOperateRecord.setPatientReserveRecordId(patientReserveRecord.getId());
        patientReserveOperateRecord.setType(type);
        patientReserveOperateRecord.setCurrentProcedure(currentProcedure);
        patientReserveOperateRecord.setTotalProcedure(totalProcedure);
        patientReserveOperateRecord.setUserType(userType);
        patientReserveOperateRecord.setUserId(userId);
        patientReserveOperateRecord.setBizStatus(bizStatus);
        return patientReserveOperateRecord;
    }

    public static TreatmentReserveExecuteDTO buildSaveTreatmentReserveExecuteDTO(PatientReserveRecord patientReserveRecord) {
        TreatmentReserveExecuteDTO treatmentReserveExecuteDTO = new TreatmentReserveExecuteDTO();
        treatmentReserveExecuteDTO.setHosDistId(patientReserveRecord.getHosDistId());
        treatmentReserveExecuteDTO.setExecuteType("init");
        treatmentReserveExecuteDTO.setPatName(patientReserveRecord.getPatName());
        treatmentReserveExecuteDTO.setAccessPatId(patientReserveRecord.getAccessPatId());
        treatmentReserveExecuteDTO.setPatCardType(patientReserveRecord.getPatCardType());
        treatmentReserveExecuteDTO.setPatCardNo(patientReserveRecord.getPatCardNo());
        treatmentReserveExecuteDTO.setAccessDocId(patientReserveRecord.getAccessDocId());
        treatmentReserveExecuteDTO.setAccessDeptId(patientReserveRecord.getAccessDeptId());
        treatmentReserveExecuteDTO.setTreatmentDate(patientReserveRecord.getTreatmentDate());
        treatmentReserveExecuteDTO.setStartTime(patientReserveRecord.getStartTime());
        treatmentReserveExecuteDTO.setEndTime(patientReserveRecord.getEndTime());
        treatmentReserveExecuteDTO.setTreatmentLocationCode(patientReserveRecord.getTreatmentLocationCode());
        treatmentReserveExecuteDTO.setTreatmentLocation(patientReserveRecord.getTreatmentLocation());
        treatmentReserveExecuteDTO.setItemCode(patientReserveRecord.getItemCode());
        treatmentReserveExecuteDTO.setTreatmentItem(patientReserveRecord.getTreatmentItem());
        treatmentReserveExecuteDTO.setItemSubItem(patientReserveRecord.getItemSubItem());
        treatmentReserveExecuteDTO.setTreatmentReserveNo(patientReserveRecord.getId().toString());
        return treatmentReserveExecuteDTO;
    }

    public static PatientReserveRecordDTO buildGetTreatmentReservePage(Doctor doctor, TreatmentReservePageAO treatmentReservePageAO) {
        BaseDTO baseDTO = CommonTool.buildBaseDTO(treatmentReservePageAO.getPageNum(), treatmentReservePageAO.getPageSize());
        PatientReserveRecordDTO patientReserveRecordDTO = new PatientReserveRecordDTO();
        patientReserveRecordDTO.setPageNum(baseDTO.getPageNum());
        patientReserveRecordDTO.setPageSize(baseDTO.getPageSize());
        patientReserveRecordDTO.setDoctorId(doctor != null ? doctor.getId() : null);
        patientReserveRecordDTO.setAccessDeptId(doctor != null ? doctor.getMainDeptId() : null);
        patientReserveRecordDTO.setPatientUserId(ReqComTool.getUserType() == 1 ? ReqComTool.getUserId() : null);
        return patientReserveRecordDTO;
    }

    public static PatientReserveRecordVO buildPatientReserveRecordVO(DoctorService doctorService, PatientReserveRecord patientReserveRecord, Map<Long, List<PatientReserveOperateRecord>> patientReserveOperateRecordMap) {
        PatientReserveRecordVO patientReserveRecordVO = CommonTool.copyProperties(patientReserveRecord, PatientReserveRecordVO.class);
        List<PatientReserveOperateRecord> list = patientReserveOperateRecordMap.get(patientReserveRecordVO.getId());
        List<PatientReserveOperateRecordVO> operateRecords = CommonTool.copyPropertiesList(list, PatientReserveOperateRecordVO.class);
        boolean confirmStatus = true;
        for (PatientReserveOperateRecordVO operateRecord : operateRecords) {
            operateRecord.setUserName(buildPatientReserveRecordVO2UserName(doctorService, patientReserveRecord, operateRecord));
            if (operateRecord.getType() == 0 || operateRecord.getType() == 2) {
                operateRecord.setConfirmStatus(1);
            }
            if (confirmStatus && operateRecord.getType() == 1 && operateRecord.getBizStatus() == 0) {
                operateRecord.setConfirmStatus(operateRecord.getUserType() == 0 && operateRecord.getUserId().equals(ReqComTool.getUserId()) ? 0 : 1);
                confirmStatus = false;
            }
        }
        patientReserveRecordVO.setOperateRecords(operateRecords);
        return patientReserveRecordVO;
    }

    private static String buildPatientReserveRecordVO2UserName(DoctorService doctorService, PatientReserveRecord patientReserveRecord, PatientReserveOperateRecordVO operateRecord) {
        if (operateRecord.getUserType() == 0) {
            return patientReserveRecord.getDoctorName();
        }
        if (operateRecord.getUserType() == 1) {
            return patientReserveRecord.getPatName();
        }
        if (operateRecord.getUserType() == 2) {
            Long userId = operateRecord.getUserId();
            if (userId == null) {
                return null;
            }
            Doctor doctor = doctorService.findById(userId);
            return doctor == null ? null : doctor.getName();
        }
        return null;
    }

    public static TreatmentReserveExecuteDTO buildCancelTreatmentReserveExecuteDTO(PatientReserveRecord patientReserveRecord) {
        TreatmentReserveExecuteDTO treatmentReserveExecuteDTO = new TreatmentReserveExecuteDTO();
        treatmentReserveExecuteDTO.setHosDistId(patientReserveRecord.getHosDistId());
        treatmentReserveExecuteDTO.setExecuteType("cancel");
        treatmentReserveExecuteDTO.setPatName(patientReserveRecord.getPatName());
        treatmentReserveExecuteDTO.setAccessPatId(patientReserveRecord.getAccessPatId());
        treatmentReserveExecuteDTO.setPatCardType(patientReserveRecord.getPatCardType());
        treatmentReserveExecuteDTO.setPatCardNo(patientReserveRecord.getPatCardNo());
        treatmentReserveExecuteDTO.setAccessDocId(patientReserveRecord.getAccessDocId());
        treatmentReserveExecuteDTO.setAccessDeptId(patientReserveRecord.getAccessDeptId());
        treatmentReserveExecuteDTO.setTreatmentDate(patientReserveRecord.getTreatmentDate());
        treatmentReserveExecuteDTO.setStartTime(patientReserveRecord.getStartTime());
        treatmentReserveExecuteDTO.setEndTime(patientReserveRecord.getEndTime());
        treatmentReserveExecuteDTO.setTreatmentLocationCode(patientReserveRecord.getTreatmentLocationCode());
        treatmentReserveExecuteDTO.setTreatmentLocation(patientReserveRecord.getTreatmentLocation());
        treatmentReserveExecuteDTO.setItemCode(patientReserveRecord.getItemCode());
        treatmentReserveExecuteDTO.setTreatmentItem(patientReserveRecord.getTreatmentItem());
        treatmentReserveExecuteDTO.setItemSubItem(patientReserveRecord.getItemSubItem());
        treatmentReserveExecuteDTO.setAccessReserveNo(patientReserveRecord.getAccessReserveNo());
        return treatmentReserveExecuteDTO;
    }

    public static PatientReserveOperateRecord dealPatientReserveOperateRecord(Doctor doctor, List<PatientReserveOperateRecord> reserveOperateRecords, ConfirmTreatmentReserveOperateAO confirmTreatmentReserveOperateAO) throws BizException {
        PatientReserveOperateRecord patientReserveOperateRecord = getPatientReserveOperateRecordById(reserveOperateRecords, confirmTreatmentReserveOperateAO.getPatientReserveOperateRecordId());
        CommonTool.checkObj(patientReserveOperateRecord, "90000007");
        if (ReqComTool.getUserType() == 0) {
            if (!(doctor.getSecretaryFlag() == 1 && patientReserveOperateRecord.getUserType() == 2)) {
                CommonTool.throwBizException("90000013");
            }
        }
        if (ReqComTool.getUserType() == 1) {
            if (!patientReserveOperateRecord.getUserId().equals(ReqComTool.getUserId())) {
                CommonTool.throwBizException("90000013");
            }
        }
        Integer beforeCheck = 0;
        for (PatientReserveOperateRecord reserveOperateRecord : reserveOperateRecords) {
            if (reserveOperateRecord.getBizStatus() == 0 && !reserveOperateRecord.getId().equals(patientReserveOperateRecord.getId())) {
                beforeCheck = 1;
            }
            if (beforeCheck == 1) {
                CommonTool.throwBizException("90000013");
            }
            if (reserveOperateRecord.getBizStatus() == 0 && reserveOperateRecord.getId().equals(patientReserveOperateRecord.getId())) {
                break;
            }
        }
        return patientReserveOperateRecord;
    }

    private static PatientReserveOperateRecord getPatientReserveOperateRecordById(List<PatientReserveOperateRecord> reserveOperateRecords, Long id) {
        for (PatientReserveOperateRecord reserveOperateRecord : reserveOperateRecords) {
            if (reserveOperateRecord.getId().equals(id)) {
                return reserveOperateRecord;
            }
        }
        return null;
    }

    public static boolean checkPatientReserveBizStatus(List<PatientReserveOperateRecord> reserveOperateRecords) {
        if (CollectionUtils.isEmpty(reserveOperateRecords)) {
            return true;
        }
        for (PatientReserveOperateRecord reserveOperateRecord : reserveOperateRecords) {
            if (reserveOperateRecord.getBizStatus() == 0) {
                return false;
            }
        }
        return true;
    }
}
